﻿Public Class frmBalloon
    Public mLocation As New System.Drawing.Point
    Public bOnTop As Boolean = False
    Public _Client As clsClientConfiguration.clsClientConfigs.sClientSettings.sClient
    Private WithEvents tFade As New System.Timers.Timer
    Private WithEvents tLoc As New System.Timers.Timer
    Public _FadeTimeOut As Double = 2000
    Public Enum eFadeOption
        FadeIn
        FadeOut
    End Enum
    Public Shared MyFade As eFadeOption = eFadeOption.FadeIn
    Public ReadOnly Property MyPosition() As System.Drawing.Point
        Get
            Return mLocation
        End Get
    End Property
    Public Sub ShowBalloon()
        Try
            If Me.InvokeRequired Then
                Dim iShowBalloon As New invShowBalloon(AddressOf ShowBalloon)
                Me.Invoke(iShowBalloon)
            Else
                Me.Opacity = 0.0001
                Me.Visible = True
                Me.Enabled = False
            End If
        Catch ex As Exception

        End Try
    End Sub
    Delegate Sub invShowBalloon()

    Public Function CloseBalloon() As Boolean
        Try
            MyFade = eFadeOption.FadeOut
            Fade()
            Return True
        Catch ex As Exception
            Reset()
            Return False
        End Try
    End Function

    Private Sub Balloon_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        On Error Resume Next
        _FadeThread.Abort()
        _SetOpThread.Abort()
        _FadeThread = Nothing
        _SetOpThread = Nothing
    End Sub


    Delegate Sub fFade()
    Private _FadeThread As Threading.Thread
    Private _SetOpThread As Threading.Thread
    Private _IsClosing As Boolean = False
    Public ReadOnly Property IsClosing() As Boolean
        Get
            Return _IsClosing
        End Get
    End Property
    Private Sub Fade()
        Try
            If MyFade = eFadeOption.FadeOut Then
                _IsClosing = True
                While Me.Opacity > 0
                    Dim _SetOpThread As New Threading.Thread(AddressOf SetOpacity)
                    _SetOpThread.Start(Me.Opacity - 0.05)
                    Threading.Thread.Sleep(0)
                End While
                Reset()
                RaiseEvent BalloonHidden()
            Else
                While Me.Opacity < 1
                    Dim _SetOpThread As New Threading.Thread(AddressOf SetOpacity)
                    _SetOpThread.Start(Me.Opacity + 0.01)
                    Threading.Thread.Sleep(0)
                End While
                If _FadeTimeOut > -1 Then
                    tFade.Interval = _FadeTimeOut
                    tFade.AutoReset = False
                    MyFade = eFadeOption.FadeOut
                    tFade.Enabled = True
                Else
                    'timer for window position
                    tLoc.AutoReset = True
                    tLoc.Interval = 150
                    tLoc.Enabled = True
                End If
            End If
        Catch ex As Exception

        End Try
    End Sub
    Delegate Sub ResetMe()
    Private Sub Reset()
        Try
            If Me.InvokeRequired Then
                Dim mRes As New ResetMe(AddressOf Reset)
                Me.Invoke(mRes)
            Else
                Me.Visible = False
                Me.Opacity = 100
                _IsClosing = False
                Me.Enabled = True
                txtBalloon.Text = ""
            End If
        Catch ex As Exception

        End Try
    End Sub
    Delegate Sub SetOp(ByVal Value As Double)
    Private Sub SetOpacity(ByVal Value As Double)
        Try
            If Me.InvokeRequired Then
                Dim mInv As New SetOp(AddressOf SetOpInv)
                Me.Invoke(mInv, New Object() {Value})
            Else
                Me.Opacity = Value
            End If
        Catch ex As Exception

        End Try
    End Sub
    Private Sub SetOpInv(ByVal Value As Double)
        Me.Opacity = Value
    End Sub
    Private Sub tFade_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tFade.Elapsed
        Try
            Dim _FadeThread As New Threading.Thread(AddressOf Fade)
            _FadeThread.Start()
        Catch ex As Exception

        End Try
    End Sub

    Private Sub frmBalloon_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
        Me.BringToFront()
        'SetForegroundWindow(Me.Handle)
    End Sub

    Private Sub frmBalloon_VisibleChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.VisibleChanged
        If Me.Visible Then
            MyFade = eFadeOption.FadeIn
            Dim _FadeThread As New Threading.Thread(AddressOf Fade)
            _FadeThread.Start()
        End If
    End Sub

    Delegate Sub invSetFadeTimeout(ByVal TimeOut As Double)
    Private Sub SetFInvoked(ByVal TimeOut As Double)
        _FadeTimeOut = TimeOut
    End Sub
    Public Sub SetFadeTimeOut(ByVal TimeOut As Double)
        If Me.InvokeRequired Then
            Dim iSetTimeOut As New invSetFadeTimeout(AddressOf SetFInvoked)
            Me.Invoke(iSetTimeOut, New Object() {TimeOut})
        Else
            _FadeTimeOut = TimeOut
        End If
    End Sub
    Delegate Sub invSetClient(ByVal aClient As clsClientConfiguration.clsClientConfigs.sClientSettings.sClient)
    Private Sub SetCInvoked(ByVal aClient As clsClientConfiguration.clsClientConfigs.sClientSettings.sClient)
        _Client = aClient
        txtBalloon.Multiline = False
        iLineHeight = txtBalloon.Height
        txtBalloon.Multiline = True
        txtBalloon.Height = 0
        With aClient
            txtBalloon.Text = ""
            AddTxt("Client:" & vbTab & .GuiController.ClientLocation)
            AddTxt("")
            AddTxt("Queue version:" & vbTab & .GuiController.Queue.Version)
            AddTxt("")
            AddTxt("Active slot:" & vbTab & .GuiController.Queue.Current & vbTab & "Status:" & vbTab & .GuiController.Queue.ActiveSlot.Status)
            AddTxt("Project:" & vbTab & .GuiController.Queue.ActiveSlot.Project.Project & " (Run " & .GuiController.Queue.ActiveSlot.Project.Run & " Clone " & .GuiController.Queue.ActiveSlot.Project.Clone & " Gen " & .GuiController.Queue.ActiveSlot.Project.Gen & ")")
            If ProjectInfo.KnownProject(.GuiController.Queue.ActiveSlot.Project.Project) Then
                AddTxt("No. atoms:" & vbTab & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).NumberOfAtoms & vbTab & "Points:" & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).Credit)
                AddTxt("Core:" & vbTab & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).Code & vbTab & "Contact:" & vbTab & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).Contact)
            Else
                AddTxt("No. atoms:" & vbTab & "Unkown" & vbTab & "Points:" & vbTab & "Unknown")
                AddTxt("Core:" & vbTab & "Unkown" & "Contact:" & vbTab & "Unkown")
            End If
            AddTxt("Issued:" & vbTab & .GuiController.Queue.ActiveSlot.Issued.ToShortDateString & " " & .GuiController.Queue.ActiveSlot.Issued.ToLongTimeString)
            AddTxt("Start time:" & vbTab & .GuiController.Queue.ActiveSlot.TimeData.BeginTime.ToShortDateString & " " & .GuiController.Queue.ActiveSlot.TimeData.BeginTime.ToLongTimeString)
            AddTxt("Expires:" & vbTab & .GuiController.Queue.ActiveSlot.Expires.ToShortDateString & " " & .GuiController.Queue.ActiveSlot.Expires.ToLongTimeString)
            If ProjectInfo.KnownProject(.GuiController.Queue.ActiveSlot.Project.Project) Then
                AddTxt("Due:" & vbTab & .GuiController.Queue.ActiveSlot.Issued.AddDays(Mid(ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays, 1, ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays.IndexOf("."))).ToShortDateString & " " & .GuiController.Queue.ActiveSlot.Issued.AddDays(Mid(ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays, 1, ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays.IndexOf("."))).ToLongTimeString)
            Else
                AddTxt("Due:" & vbTab & "Unkown")
            End If
            AddTxt("")
            If .GuiController.Queue.ActiveSlot.Status = "1" And .GuiController.Running(True) Then
                AddTxt("-Client working:")
                Dim pClient As Short = .GuiController.Queue.Progress
                Dim fClient As TimeSpan = .GuiController.Queue.tsFrame
                If pClient >= 0 Then
                    If fClient.TotalSeconds > 0 Then
                        AddTxt("Progress:" & vbTab & pClient.ToString & vbTab & "Percentage time:" & vbTab & fClient.ToString)
                    Else
                        AddTxt("Progress:" & vbTab & pClient.ToString & vbTab & "Percentage time:" & vbTab & "Unkown")
                    End If
                Else
                    AddTxt("Progress:" & vbTab & "Unknown" & vbTab & "Percentage time:" & vbTab & "Unknown")
                End If
                If .GuiController.Queue.Eta <> #1/1/2000# Then
                    AddTxt("Eta:" & vbTab & .GuiController.Queue.Eta.ToShortDateString & " " & .GuiController.Queue.Eta.ToLongTimeString)
                Else
                    AddTxt("Eta:" & vbTab & "Unkown")
                End If
            Else
                AddTxt("Client not running!")
            End If
            AddTxt("")
            If .GuiController.Queue.TotalUploadFailures > 0 Then AddTxt("Total upload failures:" & vbTab & vbTab & .GuiController.Queue.TotalUploadFailures.ToString)
            If .GuiController.Queue.PerformanceFraction <> "" Then AddTxt("Performance fraction:" & vbTab & vbTab & .GuiController.Queue.PerformanceFraction)
            If .GuiController.Queue.DownloadRate <> "" Then AddTxt("Download rate:" & vbTab & vbTab & .GuiController.Queue.DownloadRate)
            If .GuiController.Queue.UploadRate <> "" Then AddTxt("Upload rate:" & vbTab & vbTab & .GuiController.Queue.UploadRate)
        End With
        Me.Height = 12 + txtBalloon.Height + 46
        Me.Width = 94 + txtBalloon.Width
        txtBalloon.Enabled = False
    End Sub
    Private iLineHeight As Int16 = 0
    Public Sub SetClient(ByVal aClient As clsClientConfiguration.clsClientConfigs.sClientSettings.sClient)
        If Me.InvokeRequired Then
            Dim iSetClient As New invSetClient(AddressOf SetCInvoked)
            Me.Invoke(iSetClient, New Object() {aClient})
        Else
            _Client = aClient
            txtBalloon.Multiline = False
            iLineHeight = txtBalloon.Height
            txtBalloon.Multiline = True
            txtBalloon.Height = 0
            With aClient
                txtBalloon.Text = ""
                AddTxt("Client:" & vbTab & .GuiController.ClientLocation)
                AddTxt("")
                AddTxt("Queue version:" & vbTab & .GuiController.Queue.Version)
                AddTxt("")
                AddTxt("Active slot:" & vbTab & .GuiController.Queue.Current & vbTab & "Status:" & vbTab & .GuiController.Queue.ActiveSlot.Status)
                AddTxt("Project:" & vbTab & .GuiController.Queue.ActiveSlot.Project.Project & " (Run " & .GuiController.Queue.ActiveSlot.Project.Run & " Clone " & .GuiController.Queue.ActiveSlot.Project.Clone & " Gen " & .GuiController.Queue.ActiveSlot.Project.Gen & ")")
                If ProjectInfo.KnownProject(.GuiController.Queue.ActiveSlot.Project.Project) Then
                    AddTxt("No. atoms:" & vbTab & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).NumberOfAtoms & vbTab & "Points:" & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).Credit)
                    AddTxt("Core:" & vbTab & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).Code & vbTab & "Contact:" & vbTab & ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).Contact)
                Else
                    AddTxt("No. atoms:" & vbTab & "Unkown" & vbTab & "Points:" & vbTab & "Unknown")
                    AddTxt("Core:" & vbTab & "Unkown" & "Contact:" & vbTab & "Unkown")
                End If
                AddTxt("Issued:" & vbTab & .GuiController.Queue.ActiveSlot.Issued.ToShortDateString & " " & .GuiController.Queue.ActiveSlot.Issued.ToLongTimeString)
                AddTxt("Start time:" & vbTab & .GuiController.Queue.ActiveSlot.TimeData.BeginTime.ToShortDateString & " " & .GuiController.Queue.ActiveSlot.TimeData.BeginTime.ToLongTimeString)
                AddTxt("Expires:" & vbTab & .GuiController.Queue.ActiveSlot.Expires.ToShortDateString & " " & .GuiController.Queue.ActiveSlot.Expires.ToLongTimeString)
                If ProjectInfo.KnownProject(.GuiController.Queue.ActiveSlot.Project.Project) Then
                    AddTxt("Due:" & vbTab & .GuiController.Queue.ActiveSlot.Issued.AddDays(Mid(ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays, 1, ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays.IndexOf("."))).ToShortDateString & " " & .GuiController.Queue.ActiveSlot.Issued.AddDays(Mid(ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays, 1, ProjectInfo.Project(.GuiController.Queue.ActiveSlot.Project.Project).PreferredDays.IndexOf("."))).ToLongTimeString)
                Else
                    AddTxt("Due:" & vbTab & "Unkown")
                End If
                AddTxt("")
                If .GuiController.Queue.ActiveSlot.Status = "1" And .GuiController.Running(True) Then
                    AddTxt("-Client working:")
                    Dim pClient As Short = .GuiController.Queue.Progress
                    Dim fClient As TimeSpan = .GuiController.Queue.tsFrame
                    If pClient >= 0 Then
                        If fClient.TotalSeconds > 0 Then
                            AddTxt("Progress:" & vbTab & pClient.ToString & vbTab & "Percentage time:" & vbTab & fClient.ToString)
                        Else
                            AddTxt("Progress:" & vbTab & pClient.ToString & vbTab & "Percentage time:" & vbTab & "Unkown")
                        End If
                    Else
                        AddTxt("Progress:" & vbTab & "Unknown" & vbTab & "Percentage time:" & vbTab & "Unknown")
                    End If
                    If .GuiController.Queue.Eta <> #1/1/2000# Then
                        AddTxt("Eta:" & vbTab & .GuiController.Queue.Eta.ToShortDateString & " " & .GuiController.Queue.Eta.ToLongTimeString)
                    Else
                        AddTxt("Eta:" & vbTab & "Unkown")
                    End If
                Else
                    AddTxt("Client not running!")
                End If
                AddTxt("")
                If .GuiController.Queue.TotalUploadFailures > 0 Then AddTxt("Total upload failures:" & vbTab & vbTab & .GuiController.Queue.TotalUploadFailures.ToString)
                If .GuiController.Queue.PerformanceFraction <> "" Then AddTxt("Performance fraction:" & vbTab & vbTab & .GuiController.Queue.PerformanceFraction)
                If .GuiController.Queue.DownloadRate <> "" Then AddTxt("Download rate:" & vbTab & vbTab & .GuiController.Queue.DownloadRate)
                If .GuiController.Queue.UploadRate <> "" Then AddTxt("Upload rate:" & vbTab & vbTab & .GuiController.Queue.UploadRate)
            End With
            Me.Height = 12 + txtBalloon.Height + 46
            Me.Width = 94 + txtBalloon.Width
            txtBalloon.Enabled = False
        End If
    End Sub
    Private iMaxLineWidth As Int16
    Delegate Sub AddText(ByVal Text As String)
    Private Sub invAddText(ByVal Text As String)
        Dim txtWidth As New Label
        txtWidth.AutoSize = True
        txtWidth.Text = Text
        Me.Controls.Add(txtWidth)
        If txtWidth.Width > iMaxLineWidth Then
            iMaxLineWidth = txtWidth.Width
            txtBalloon.Width = txtWidth.Width + 20
        End If
        Me.Controls.Remove(txtWidth)
        txtBalloon.Text &= Text & vbNewLine
        txtBalloon.Height += iLineHeight
    End Sub
    Private Sub AddTxt(ByVal Text As String)
        If txtBalloon.InvokeRequired Then
            Dim iAdd As New AddText(AddressOf invAddText)
            txtBalloon.Invoke(iAdd, New Object() {Text})
        Else
            Dim txtWidth As New Label
            txtWidth.AutoSize = True
            txtWidth.Text = Text
            Me.Controls.Add(txtWidth)
            If txtWidth.Width > iMaxLineWidth Then
                iMaxLineWidth = txtWidth.Width
                txtBalloon.Width = txtWidth.Width + 20
            End If
            Me.Controls.Remove(txtWidth)
            txtBalloon.Text &= Text & vbNewLine
            txtBalloon.Height += iLineHeight
        End If
    End Sub
    Delegate Sub invSetLocation(ByVal Position As System.Drawing.Point)
    Private Sub SetLInvoked(ByVal Position As System.Drawing.Point)
        Me.Left = Position.X - (Me.ClientSize.Width - 50)
        Me.Top = Position.Y - Me.Height
    End Sub
    Public Sub SetLocation(ByVal Position As System.Drawing.Point)
        If Me.InvokeRequired Then
            Dim iSetLocation As New invSetLocation(AddressOf SetLInvoked)
            Me.Invoke(iSetLocation, New Object() {Position})
        Else
            mLocation = Position
            Me.Left = Position.X - (Me.ClientSize.Width - 50)
            Me.Top = Position.Y - Me.Height
        End If
    End Sub
    Public Event BalloonHidden()



    Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        MyFade = eFadeOption.FadeOut
        Fade()
    End Sub

    Private Sub tLoc_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tLoc.Elapsed
        Dim cPos As System.Drawing.Point = System.Windows.Forms.Cursor.Position
        If Not (cPos.X > (mLocation.X - 3) And cPos.X < (mLocation.X + 3) And cPos.Y > (mLocation.Y - 3) And cPos.Y < (mLocation.Y + 3)) Then
            tLoc.Enabled = False
            CloseBalloon()
        End If
    End Sub
End Class